package com.farm.project.service.impl;

import com.farm.project.domain.Project;
import com.farm.project.domain.ProjectCompany;
import com.farm.project.domain.ProjectGradation;
import com.farm.project.domain.Task;
import com.farm.core.time.TimeTool;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.farm.project.dao.CompanyDaoInter;
import com.farm.project.dao.ProjectDaoInter;
import com.farm.project.dao.ProjectGradationDaoInter;
import com.farm.project.dao.ProjectcompanyDaoInter;
import com.farm.project.dao.TaskDaoInter;
import com.farm.project.dao.TaskFileDaoInter;
import com.farm.project.service.FieldServiceInter;
import com.farm.project.service.ProjectFieldinsServiceInter;
import com.farm.project.service.ProjectServiceInter;
import com.farm.project.service.ProjectcompanyServiceInter;
import com.sun.star.uno.RuntimeException;
import com.farm.core.sql.query.DBRule;
import com.farm.core.sql.query.DBRuleList;
import com.farm.core.sql.query.DBSort;
import com.farm.core.sql.query.DataQuery;
import com.farm.core.sql.query.DataQuerys;
import com.farm.core.sql.result.DataResult;
import com.farm.core.sql.result.ResultsHandle;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;
import com.farm.core.auth.domain.LoginUser;

/* *
 *功能：项目服务层实现类
 *详细：
 *
 *版本：v0.1
 *作者：FarmCode代码工程
 *日期：20150707114057
 *说明：
 */
@Service
public class ProjectServiceImpl implements ProjectServiceInter {
	@Resource
	private ProjectDaoInter projectDaoImpl;
	@Resource
	private ProjectGradationDaoInter projectgradationDaoImpl;
	@Resource
	private ProjectFieldinsServiceInter projectFieldinsServiceImpl;
	@Resource
	private TaskDaoInter taskDaoImpl;
	@Resource
	private TaskFileDaoInter taskfileDaoImpl;
	@Resource
	private FieldServiceInter fieldServiceImpl;
	@Resource
	private CompanyDaoInter companyDaoImpl;
	@Resource
	private ProjectcompanyDaoInter projectcompanyDaoImpl;
	private static final Logger log = Logger.getLogger(ProjectServiceImpl.class);

	@Override
	@Transactional
	public Project insertProjectEntity(Project entity, LoginUser user) {
		if (StringUtils.isNotBlank(entity.getGradationid())) {
			ProjectGradation gradation = projectgradationDaoImpl.getEntity(entity.getGradationid());
			entity.setGradationname(gradation.getName());
		}
		entity.setCuser(user.getId());
		entity.setLivetime(TimeTool.getTimeDate14());
		entity.setCtime(TimeTool.getTimeDate14());
		entity.setEuser(user.getId());
		entity.setEtime(TimeTool.getTimeDate14());
		Project project = projectDaoImpl.insertEntity(entity);
		projectFieldinsServiceImpl.loadSysField(project.getId(), user);
		return project;
	}

	@Override
	@Transactional
	public Project editProjectEntity(Project entity, LoginUser user) {
		Project entity2 = projectDaoImpl.getEntity(entity.getId());
		if (StringUtils.isNotBlank(entity2.getGradationid())) {
			ProjectGradation gradation = projectgradationDaoImpl.getEntity(entity.getGradationid());
			entity2.setGradationname(gradation.getName());
		}
		entity2.setGradationid(entity.getGradationid());
		entity2.setState(entity.getState());
		entity2.setLivetime(TimeTool.getTimeDate14());
		entity2.setName(entity.getName());
		entity2.setPcontent(entity.getPcontent());
		entity2.setEuser(user.getId());
		entity2.setEtime(TimeTool.getTimeDate14());
		entity2.setTypeid(entity.getTypeid());
		if (hasLiveTask(entity.getId()) && (entity2.getState().equals("2") || entity2.getState().equals("3"))) {
			throw new RuntimeException("该项目有任务未归档,不可关闭或删除!");
		}
		projectDaoImpl.editEntity(entity2);
		return entity2;
	}

	@Override
	@Transactional
	public void deleteProjectEntity(String id, LoginUser user) {
		Project project = projectDaoImpl.getEntity(id);
		project.setState("3");
		editProjectEntity(project, user);
	}

	@Override
	@Transactional
	public Project getProjectEntity(String id) {
		// TODO 自动生成代码,修改后请去除本注释
		if (id == null) {
			return null;
		}
		return projectDaoImpl.getEntity(id);
	}

	@Override
	@Transactional
	public DataQuery createProjectSimpleQuery(DataQuery query) {
		DataQuery dbQuery = DataQuery.init(query,
				"PLOGS_PROJECT a left join ALONE_AUTH_USER b on a.cuser=b.id left join PLOGS_PROJECT_TYPE c on a.typeid=c.id left join PLOGS_PROJECT_RE_COMPANY d on d.PROJECTID=a.id left join PLOGS_PROJECT_COMPANY e on d.COMPANYID=e.id",
				"a.ID as ID,TYPEID,GRADATIONNAME,GRADATIONID,a.STATE as STATE,a.LIVETIME as LIVETIME,a.NAME as NAME,a.CUSER as CUSER,c.name as TYPENAME,a.CTIME as CTIME,b.name as CUSERNAME,e.NAME as COMPANY");
		return dbQuery;
	}

	@Override
	@Transactional
	public void editType(String projectId, String typeId, LoginUser currentUser) {
		Project project = projectDaoImpl.getEntity(projectId);
		project.setTypeid(typeId);
		projectDaoImpl.editEntity(project);
	}

	@Override
	@Transactional
	public ProjectGradation getGradation(String projectId) {
		Project project = projectDaoImpl.getEntity(projectId);
		if (project == null) {
			throw new RuntimeException("projectId is not to project!");
		}
		ProjectGradation gradation = projectgradationDaoImpl.getEntity(project.getGradationid());
		return gradation;
	}

	@Override
	@Transactional
	public List<Project> getliveProjects(LoginUser currentUser, String name) throws SQLException {
		DataQuery dbQuery = DataQuery.getInstance(1,
				"a.ID as ID,a.NAME as NAME,a.STATE as STATE,a.LIVETIME as LIVETIME,a.GRADATIONID as GRADATIONID,a.GRADATIONNAME as GRADATIONNAME,c.name as COMPANYNAME",
				"PLOGS_PROJECT a left join PLOGS_PROJECT_USER g on a.id=g.PROJECTID left join PLOGS_PROJECT_RE_COMPANY b on a.id=b.PROJECTID left join PLOGS_PROJECT_COMPANY c on b.COMPANYID=c.id");
		dbQuery.addRule(new DBRule("STATE", "1", "="));
		if (StringUtils.isNotBlank(name)) {
			DataQuerys.wipeVirus(name);
			dbQuery.addSqlRule(" and (a.name like '%" + name + "%' or c.name like '%" + name + "%')");
		}
		dbQuery.addRule(new DBRule("g.USERID", currentUser.getId(), "="));
		dbQuery.setPagesize(100);
		dbQuery.setDistinct(true);
		dbQuery.setNoCount();
		dbQuery.addSort(new DBSort("LIVETIME", "DESC"));
		List<Project> list = dbQuery.search().getObjectList(Project.class);
		return list;
	}

	@Override
	@Transactional
	public void editProjectGradation(String projectid, String gradationId, LoginUser currentUser) {
		ProjectGradation gradation = projectgradationDaoImpl.getEntity(gradationId);
		Project project = projectDaoImpl.getEntity(projectid);
		project.setEtime(TimeTool.getTimeDate14());
		project.setEuser(currentUser.getId());
		project.setGradationid(gradation.getId());
		project.setGradationname(gradation.getName());
		projectDaoImpl.editEntity(project);
	}

	@Override
	@Transactional
	public void refreshLiveTime(String projectid) {
		Project project = projectDaoImpl.getEntity(projectid);
		project.setLivetime(TimeTool.getTimeDate14());
		projectDaoImpl.editEntity(project);
	}

	@Override
	public DataResult getProjectsForView(DataQuery dbQuery, DBSort fieldSort, Integer page, Integer pagesize,
			LoginUser currentUser) throws SQLException {
		if (page == null) {
			page = 1;
		}
		String leftSql = "";
		if (fieldSort != null && fieldServiceImpl.getFieldByUUID(fieldSort.getSortTitleText()) != null) {
			// 查詢條件是屬性UUID
			leftSql = " left join PLOGS_PROJECT_FIELDINS b on b.PROJECTID=a.id and b.UUID='"
					+ fieldSort.getSortTitleText() + "'";
			dbQuery.addSort(new DBSort("b.VALTITLE", fieldSort.getSortTypeText()));
		} else {
			dbQuery.setDefaultSort(new DBSort("LIVETIME", "desc"));
		}
		dbQuery = DataQuery.init(dbQuery,
				"PLOGS_PROJECT a left join PLOGS_PROJECT_USER g on g.PROJECTID=a.id left join PLOGS_PROJECT_RE_COMPANY c1 on c1.projectid=a.id left join PLOGS_PROJECT_COMPANY c2 on c2.id=c1.companyid"
						+ leftSql,
				"a.ID as ID,c2.name as companyname,a.NAME as NAME,a.STATE as STATE,a.LIVETIME as LIVETIME,a.GRADATIONNAME as GRADATIONNAME,a.TYPEID as TYPEID");
		dbQuery.addRule(new DBRule("STATE", "3", "!="));
		dbQuery.addRule(new DBRule("G.USERID", currentUser.getId(), "="));
		dbQuery.setPagesize(pagesize);
		dbQuery.setCurrentPage(page);
		dbQuery.setDistinct(true);
		DataResult result = dbQuery.search();
		result.runHandle(new ResultsHandle() {
			@Override
			public void handle(Map<String, Object> row) {
				// 查詢自定義屬性
				String projectId = (String) row.get("ID");
				String state = (String) row.get("STATE");
				// 0.停用1.激活2.关闭3.删除
				if (state.equals("0")) {
					row.put("STATETITLE", "停用");
				}
				if (state.equals("1")) {
					row.put("STATETITLE", "激活");
				}
				if (state.equals("2")) {
					row.put("STATETITLE", "关闭");
				}
				if (state.equals("3")) {
					row.put("STATETITLE", "删除");
				}
				Map<String, Object> fields = projectFieldinsServiceImpl.getProjectFieldDic(projectId);
				row.putAll(fields);
			}
		});
		return result;
	}

	@Override
	@Transactional
	public List<ProjectGradation> getProjectHasGradation(String projectId) {
		List<String> gradationids = taskDaoImpl.getGradationIdsByProjectId(projectId);
		List<ProjectGradation> result = new ArrayList<>();
		for (String id : gradationids) {
			result.add(projectgradationDaoImpl.getEntity(id));
		}
		Collections.sort(result, new Comparator<ProjectGradation>() {
			@Override
			public int compare(ProjectGradation o1, ProjectGradation o2) {
				return o1.getSort() - o2.getSort();
			}
		});
		return result;
	}

	@Override
	@Transactional
	public List<Task> getProjectTasks(String projectId) {
		List<Task> tasks = taskDaoImpl.selectEntitys(DBRuleList.getInstance().add(new DBRule("PSTATE", "0", "!="))
				.add(new DBRule("PROJECTID", projectId, "=")).toList());
		Collections.sort(tasks, new Comparator<Task>() {
			@Override
			public int compare(Task o1, Task o2) {
				if (o1.getDostime() != null && o2.getDostime() != null) {
					return o2.getDostime().compareTo(o1.getDostime());
				} else {
					return o2.getEtime().compareTo(o1.getEtime());
				}
			}
		});
		return tasks;
	}

	@Override
	@Transactional
	public List<Map<String, Object>> getProjectTaskFiles(String projectId) throws SQLException {
		List<Map<String, Object>> taskfiles = taskfileDaoImpl.getProjectFiles(projectId, null, null, null);
		return taskfiles;
	}

	@Override
	@Transactional
	public List<Map<String, Object>> getProjectTaskTypes(String projectId) throws SQLException {
		DataQuery dbQuery = DataQuery.getInstance(1, "PROJECTID,GRADATIONID,TASKTYPEID,TASKTYPENAME", "PLOGS_TASK");
		dbQuery.setDistinct(true);
		dbQuery.addRule(new DBRule("PROJECTID", projectId, "="));
		dbQuery.addRule(new DBRule("PSTATE", "0", "!="));
		dbQuery.addSort(new DBSort("TASKTYPENAME", "ASC"));
		dbQuery.setPagesize(1000);
		List<Map<String, Object>> list = dbQuery.search().getResultList();
		return list;
	}

	@Override
	@Transactional
	public List<Project> getliveProjects(LoginUser currentUser, String stime_yyyymmdd, String etime_yyyymmdd)
			throws SQLException {
		String boundLimitSql = "";
		if (StringUtils.isNotBlank(stime_yyyymmdd) && StringUtils.isNotBlank(etime_yyyymmdd)) {
			DataQuerys.wipeVirus(stime_yyyymmdd);
			DataQuerys.wipeVirus(etime_yyyymmdd);
			boundLimitSql = " AND ( ( DOSTIME > '" + stime_yyyymmdd.replaceAll("-", "") + "000000" + "' AND DOSTIME < '"
					+ etime_yyyymmdd.replaceAll("-", "") + "999999" + "' ) OR ( DOETIME > '"
					+ stime_yyyymmdd.replaceAll("-", "") + "000000" + "' AND DOETIME < '"
					+ etime_yyyymmdd.replaceAll("-", "") + "999999" + "' )   OR   ( DOSTIME < '"
					+ stime_yyyymmdd.replaceAll("-", "") + "000000" + "' AND DOETIME > '"
					+ etime_yyyymmdd.replaceAll("-", "") + "999999" + "' )  )";
		}
		DataQuery dbQuery = DataQuery.getInstance(1, "ID,NAME,STATE,LIVETIME,GRADATIONID,GRADATIONNAME,PCONTENT",
				"( SELECT B.ID AS ID, B. NAME AS NAME, B.STATE AS STATE, B.LIVETIME AS LIVETIME, B.GRADATIONID AS GRADATIONID, B.GRADATIONNAME AS GRADATIONNAME, count(b.id) AS PCONTENT FROM PLOGS_TASK a LEFT JOIN PLOGS_PROJECT b ON a.projectid = b.id WHERE 1 = 1 AND B.STATE = '1' AND a.PSTATE != '0' "
						+ boundLimitSql + " GROUP BY b.id ) tb");
		dbQuery.setPagesize(100);
		dbQuery.setNoCount();
		dbQuery.addSort(new DBSort("LIVETIME", "DESC"));
		List<Project> list = dbQuery.search().getObjectList(Project.class);
		return list;
	}

	@Override
	@Transactional
	public List<Task> getProjectTasks(String projectId, String stime_yyyymmdd, String etime_yyyymmdd,
			LoginUser currentUser) throws SQLException {
		DataQuery dbQuery = DataQuery.getInstance(1,
				"a.PSTATE as PSTATE,b.NAME as PCONTENT,a.ID as ID,a.TITLE as TITLE,a.READFILEID as READFILEID,a.PROJECTID as PROJECTID,a.USERID as USERID,a.PLANSTIME as PLANSTIME,a.PLANETIME as PLANETIME,a.DOSTIME as DOSTIME,a.DOETIME as DOETIME,a.PLANTIMES as PLANTIMES,a.DOTIMES as DOTIMES,a.SOURCEUSERID as SOURCEUSERID,a.RELAUSERID as RELAUSERID,a.GRADATIONID as GRADATIONID,a.GRADATIONNAME as GRADATIONNAME,a.TASKTYPEID as TASKTYPEID,a.TASKTYPENAME as TASKTYPENAME",
				"PLOGS_TASK a left join PLOGS_PROJECT b on a.PROJECTID=b.id");
		// 0：删除状态
		dbQuery.addRule(new DBRule("PSTATE", "0", "!="));
		dbQuery.setPagesize(1000);
		DataQuerys.wipeVirus(stime_yyyymmdd);
		DataQuerys.wipeVirus(etime_yyyymmdd);
		if (StringUtils.isNotBlank(projectId)) {
			dbQuery.addRule(new DBRule("PROJECTID", projectId, "="));
		}
		if (currentUser != null) {
			dbQuery.addRule(new DBRule("USERID", currentUser.getId(), "="));
		}
		if (StringUtils.isNotBlank(stime_yyyymmdd) && StringUtils.isNotBlank(etime_yyyymmdd)) {
			dbQuery.addSqlRule(" and ( ( DOSTIME > '" + stime_yyyymmdd.replaceAll("-", "") + "000000"
					+ "' AND DOSTIME < '" + etime_yyyymmdd.replaceAll("-", "") + "999999" + "' ) OR ( DOETIME > '"
					+ stime_yyyymmdd.replaceAll("-", "") + "000000" + "' AND DOETIME < '"
					+ etime_yyyymmdd.replaceAll("-", "") + "999999" + "' )   OR   ( DOSTIME < '"
					+ stime_yyyymmdd.replaceAll("-", "") + "000000" + "' AND DOETIME > '"
					+ etime_yyyymmdd.replaceAll("-", "") + "999999" + "' )  )");
		}
		List<Task> tasks = dbQuery.search().getObjectList(Task.class);
		Collections.sort(tasks, new Comparator<Task>() {
			@Override
			public int compare(Task o1, Task o2) {
				if (o1.getDostime() != null && o2.getDostime() != null) {
					return o1.getDostime().compareTo(o2.getDostime());
				} else {
					return o1.getEtime().compareTo(o2.getEtime());
				}
			}
		});
		return tasks;
	}

	@Override
	@Transactional
	public List<Map<String, Object>> getProjectTaskFiles(String projectId, String stime, String etime,
			LoginUser currentUser) throws SQLException {
		List<Map<String, Object>> taskfiles = taskfileDaoImpl.getProjectFiles(projectId, stime, etime, currentUser);
		return taskfiles;
	}

	@Override
	public List<Map<String, Object>> filterTaskTypesByTasks(List<Task> tasks,
			List<Map<String, Object>> projectTaskTypes) {
		Set<String> taskTypeids = new HashSet<>();
		for (Task task : tasks) {
			taskTypeids.add(task.getTasktypeid());
		}
		List<Map<String, Object>> raturn = new ArrayList<>();
		for (Map<String, Object> node : projectTaskTypes) {
			if (taskTypeids.contains(node.get("TASKTYPEID"))) {
				raturn.add(node);
			}
		}
		return raturn;
	}

	@Override
	public List<ProjectGradation> filterGradationByTasks(List<Task> tasks, List<ProjectGradation> projectHasGradation) {
		Set<String> gradationids = new HashSet<>();
		for (Task task : tasks) {
			gradationids.add(task.getGradationid());
		}
		List<ProjectGradation> raturn = new ArrayList<>();
		for (ProjectGradation node : projectHasGradation) {
			if (gradationids.contains(node.getId())) {
				raturn.add(node);
			}
		}
		return raturn;
	}

	@Override
	public List<Map<String, Object>> getUserTaskNums(List<String> userids, String stime_yyyymmdd, String etime_yyyymmdd)
			throws SQLException {
		String boundLimitSql = "";
		String useridsSql = "";
		for (String userid : userids) {
			if (useridsSql.equals("")) {
				useridsSql = "'" + userid + "'";
			} else {
				useridsSql = useridsSql + ",'" + userid + "'";
			}
		}
		if (StringUtils.isNotBlank(stime_yyyymmdd) && StringUtils.isNotBlank(etime_yyyymmdd)) {
			DataQuerys.wipeVirus(stime_yyyymmdd);
			DataQuerys.wipeVirus(etime_yyyymmdd);
			boundLimitSql = " AND ( ( DOSTIME > '" + stime_yyyymmdd.replaceAll("-", "") + "000000" + "' AND DOSTIME < '"
					+ etime_yyyymmdd.replaceAll("-", "") + "999999" + "' ) OR ( DOETIME > '"
					+ stime_yyyymmdd.replaceAll("-", "") + "000000" + "' AND DOETIME < '"
					+ etime_yyyymmdd.replaceAll("-", "") + "999999" + "' )   OR   ( DOSTIME < '"
					+ stime_yyyymmdd.replaceAll("-", "") + "000000" + "' AND DOETIME > '"
					+ etime_yyyymmdd.replaceAll("-", "") + "999999" + "' )  )";
		}
		DataQuery dbQuery = DataQuery.getInstance(1, "ID,NAME,TASKNUM,ORGNAME",
				"( SELECT B.ID AS ID, B. NAME AS NAME, count(b.id) AS TASKNUM, d. NAME AS orgname FROM PLOGS_TASK a LEFT JOIN alone_auth_user b ON a.USERID = b.id LEFT JOIN alone_auth_userorg c ON b.id = c.USERID LEFT JOIN alone_auth_organization d ON c.ORGANIZATIONID = d.ID WHERE 1 = 1 AND B.STATE = '1' AND a.PSTATE != '0' "
						+ boundLimitSql + " and b.id in (" + useridsSql + ") GROUP BY b.id ) tb");
		dbQuery.setPagesize(100);
		dbQuery.setNoCount();
		List<Map<String, Object>> list = dbQuery.search().getResultList();
		return list;
	}

	@Override
	public boolean hasLiveTask(String projectId) {
		DataQuery dbQuery = DataQuery.getInstance(1, "ID,PSTATE", "PLOGS_TASK");
		DataQuerys.wipeVirus(projectId);
		dbQuery.addSqlRule(" and PROJECTID='" + projectId + "' and (PSTATE!='5' and PSTATE!='0')");
		try {
			if (dbQuery.search().getTotalSize() > 0) {
				return true;
			} else {
				return false;
			}
		} catch (SQLException e) {
			throw new RuntimeException(e.getMessage());
		}
	}

	@Override
	@Transactional
	public DataResult getProjectsForManager(DataQuery query, LoginUser currentUser) {
		DataQuery dbQuery = DataQuery.init(query,
				"PLOGS_PROJECT a left join PLOGS_PROJECT_USER g on g.PROJECTID=a.id left join PLOGS_PROJECT_TYPE b on a.typeid=b.id left join PLOGS_PROJECT_RE_COMPANY c on c.projectid=a.id left join PLOGS_PROJECT_COMPANY d on d.id=c.companyid",
				"A.ID AS ID,A.CTIME AS CTIME,A.NAME AS NAME,A.STATE AS STATE,A.LIVETIME AS LIVETIME,A.GRADATIONID AS GRADATIONID,A.GRADATIONNAME AS GRADATIONNAME,A.TYPEID AS TYPEID,B.NAME AS TYPENAME,D.NAME AS COMPANYNAME");
		dbQuery.addRule(new DBRule("STATE", "3", "!="));
		dbQuery.addRule(new DBRule("G.USERID", currentUser.getId(), "="));
		dbQuery.addRule(new DBRule("G.POPTYPE", "1", "="));
		dbQuery.addSort(new DBSort("LIVETIME", "DESC"));
		dbQuery.setDistinct(true);
		try {
			return dbQuery.search();
		} catch (SQLException e) {
			throw new RuntimeException(e.getMessage());
		}
	}

	@Override
	@Transactional
	public void editProjectState(String projectid, String state, LoginUser currentUser) {
		Project project = projectDaoImpl.getEntity(projectid);
		if (!project.getState().equals("2") && state.equals("3")) {
			throw new RuntimeException("只有关闭的项目可以被删除!");
		}
		project.setState(state);
		editProjectEntity(project, currentUser);
	}

	@Override
	@Transactional
	public List<Project> getCompanyProjects(String companyid) {
		List<Project> ps = new ArrayList<>();
		List<ProjectCompany> pcs = projectcompanyDaoImpl
				.selectEntitys(DBRuleList.getInstance().add(new DBRule("COMPANYID", companyid, "=")).toList());
		for (ProjectCompany node : pcs) {
			ps.add(projectDaoImpl.getEntity(node.getProjectid()));
		}
		return ps;
	}
}
